package com.fangshi.viewmodels

import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.fangshi.TAG
import com.fangshi.api.RemoteService
import kotlinx.coroutines.*


class GarageViewModel(baseUrl: String) : ViewModel() {

    private var garageRepo: GarageRepository = GarageRepository(RemoteService.create(baseUrl))

    val selectedGarageId: MutableLiveData<String?> by lazy {
        MutableLiveData<String?>(null)
    }

    val areas: MutableLiveData<List<Area>> by lazy {
        MutableLiveData(emptyList())
    }

    val garagesDisplayed: MutableLiveData<List<Garage>> by lazy {
        MutableLiveData(emptyList())
    }

    val errMsg: MutableLiveData<String?> by lazy {
        MutableLiveData<String?>(null)
    }

    fun onAreaSelected(areaName: String) {
        val area = areas.value?.first { area -> area.areaName == areaName }
        garagesDisplayed.value = area?.garages
    }

    fun onGarageSelected(garageId: String) {
        selectedGarageId.value = garageId
    }

    fun onSwitchArea() {
        selectedGarageId.value = null
    }

    fun setBaseUrl(baseUrl: String) {
        garageRepo = GarageRepository(RemoteService.create(baseUrl))
        selectedGarageId.postValue(null)
        areas.postValue(emptyList())
        garagesDisplayed.postValue(emptyList())
        errMsg.postValue(null)
    }

    fun loadData() {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                garageRepo.getGarages().also {
                    areas.postValue(it)
                    if (it.isNotEmpty()) {
                        garagesDisplayed.postValue(it[0].garages)
                    }
                }
            } catch (e: Exception) {
                errMsg.postValue(e.message)
            }
        }
    }

    suspend fun enterGarageByScan(carNo: String): String {
        return try {
            val sGarageId = selectedGarageId.value!!
            garageRepo.addScanEnterRecord(carNo, sGarageId)
            garagesDisplayed.value?.forEach loop@{
                if(it.garageId.equals(sGarageId)){
                    it.carCount++
                    return@loop
                }
            }
            garagesDisplayed.postValue(garagesDisplayed.value)
            "槽车$carNo,扫码入库成功"
        } catch (e: Exception) {
            Log.e(TAG, e.message.toString())
            e.message ?: "网络请求异常"
        }
    }

    suspend fun exitGarageByScan(carNo: String): String {
        return try {
            val sGarageId = selectedGarageId.value!!
            garageRepo.addScanExitRecord(carNo, sGarageId)
            garagesDisplayed.value?.forEach loop@{
                if(it.garageId.equals(sGarageId)){
                    it.carCount--
                    return@loop
                }
            }
            garagesDisplayed.postValue(garagesDisplayed.value)
            "槽车$carNo,扫码出库成功"
        } catch (e: Exception) {
            e.message ?: "网络请求异常"
        }
    }

    suspend fun enterGarageByManual(carNo: String): String {
        return try {
            val sGarageId = selectedGarageId.value!!
            garageRepo.addManualEnterRecord(carNo, sGarageId)
            garagesDisplayed.value?.forEach loop@{
                if(it.garageId.equals(sGarageId)){
                    it.carCount++
                    return@loop
                }
            }
            "槽车$carNo,手动入库成功"
        } catch (e: Exception) {
            e.message ?: "网络请求异常"
        }
    }


    suspend fun exitGarageByManual(carNo: String): String {
        return try {
            val sGarageId = selectedGarageId.value!!
            garageRepo.addManualExitRecord(carNo, sGarageId)
            garagesDisplayed.value?.forEach loop@{
                if(it.garageId.equals(sGarageId)){
                    it.carCount--
                    return@loop
                }
            }
            garagesDisplayed.postValue(garagesDisplayed.value)
            "槽车$carNo,手动出库成功"
        } catch (e: Exception) {
            e.message ?: "网络请求异常"
        }
    }
}

@Suppress("UNCHECKED_CAST")
class GarageViewModelFactory(private val remoteBaseUrl: String) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(GarageViewModel::class.java)) {
            return GarageViewModel(remoteBaseUrl) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}


